<template>
  <v-container>
    <v-row>
      <v-col cols="6" class="mx-auto ">
        <p>账号信息设置</p>
        
        <v-form
          ref="form"
          v-model="valid"
          lazy-validation
          class="my-5"
          align="center"
        >
          <v-dialog
            transition="dialog-bottom-transition"
            v-model="dialog"
            max-width="600"
          >
            <template v-slot:activator="{ on, attrs }">
              <v-avatar
                color="white"
                size="75"
              >
                <img
                  :src="user.avatar"
                  alt="用户头像"
                  v-bind="attrs"
                  v-on="on"
                >
              </v-avatar>
            </template>
            <template>
              <v-card>
                <v-toolbar
                  dark
                  color="teal"
                >头像上传</v-toolbar>
                <v-card-text >
                  <h5 class="my-2">* 请选择图片上传：大小180 * 180像素支持JPG、PNG等格式，图片需小于2M</h5>
                  <div id="cut">
                    <div id="show-cropper">
                      <vueCropper
                        ref="cropper"
                        :img="option.img"
                        :outputSize="option.size"
                        :outputType="option.outputType"
                        :info="true"
                        :full="option.full"
                        :canMove="option.canMove"
                        :canMoveBox="option.canMoveBox"
                        :original="option.original"
                        :autoCrop="option.autoCrop"
                        :fixed="option.fixed"
                        :fixedNumber="option.fixedNumber"
                        :centerBox="option.centerBox"
                        :infoTrue="option.infoTrue"
                        :fixedBox="option.fixedBox"
                        :autoCropWidth="option.autoCropWidth"
                        :autoCropHeight="option.autoCropHeight"
                        @realTime="realTime"
                      ></vueCropper>

                      <input v-show="false" ref="fileRef" @change="handleChangeUpload" accept="image/jpeg,image/png" type="file" />
                      <div align="center">
                        <v-btn
                          color="blue-grey"
                          class="ma-2 px-auto white--text"
                          @click="$refs.fileRef.click()"
                        >
                          <v-icon
                            left
                            dark
                          >
                            mdi-reload
                          </v-icon>
                          重新选择
                        </v-btn>
                      </div>
                    </div>
                    
                    <div id="vertical-line"></div>
                    <div id="show-preview">
                      <div :style="{'width': previews.w + 'px', 'height': previews.h + 'px'}">
                        <div :style="previews.div">
                          <img :src="previews.url" :style="previews.img">
                        </div>
                      </div>
                      <p>预览头像</p>
                    </div>
                  </div>

                </v-card-text>

                <v-card-actions class="justify-end">
                  <v-btn
                    text
                    @click="dialog = false"
                  >关闭</v-btn>
                  <v-btn
                    text
                    @click="updateImage"
                  >确认</v-btn>
                </v-card-actions>
              </v-card>
            </template>
          </v-dialog>
          
          <v-text-field
            v-model="user.name"
            label="用户名:"
            hint="3～16个字符，支持中英文、数字"
            counter="16"
            :rules="nameRules"
            filled
            class="pt-2"
          ></v-text-field>

          <v-textarea
            filled 
            hint="请输入1~255个字符"
            label="简介:"
            :rules="introductionRules"
            counter="255"
            v-model="user.introduction"
          ></v-textarea>

          <p>个人基本信息设置</p>

          <v-radio-group
            v-model="user.gender"
            row
          >
            性别：
            <v-radio
              label="男"
              :value="false"
            ></v-radio>
            <v-radio
              label="女"
              :value="true"
            ></v-radio>
          </v-radio-group>
          <v-row
            align="center"
            justify="end"
          >
            <v-btn
              tile
              color="success"
              @click="updateAccount"
            >
              <v-icon left>mdi-tree</v-icon>
              保存
            </v-btn>
          </v-row>

        </v-form>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import {VueCropper} from 'vue-cropper'

export default {
  name: 'MyUserSet',
  components: {
    VueCropper
  },
  data:()=>({
    user: {},
    valid: true,
    nameRules: [
      v => !!v || '用户名必须填写！',
      v => (v && v.length > 2 && v.length < 17) || '用户名不合法！用户名长度必须在3到16之间！',
      v => /^[\u4E00-\u9FFFa-zA-Z]{1}[\u4E00-\u9FFFa-zA-Z0-9]{2,15}$/.test(v) || 
        '用户名不合法!用户名应该不以数字开头！'
    ],
    introductionRules: [
      v => !!v || '简介不能为空！',
      v => (v && v.length > 0 && v.length <= 255) || '简介内容限制在1-255以内！'
    ],
    dialog: false,
    previews: {},
    option: {
      img: '/upload/avatar/default.png', // 裁剪图片的地址
      info: true, // 裁剪框的大小信息
      outputSize: 1, // 裁剪生成图片的质量
      outputType: 'png', // 裁剪生成图片的格式
      canScale: true, // 图片是否允许滚轮缩放
      autoCrop: true, // 是否默认生成截图框
      canMoveBox: true, // 截图框能否拖动
      autoCropWidth: 180, // 默认生成截图框宽度
      autoCropHeight: 180, // 默认生成截图框高度
      fixedBox: true, // 固定截图框大小 不允许改变
      fixed: true, // 是否开启截图框宽高固定比例
      fixedNumber: [1, 1], // 截图框的宽高比例
      full: false, // 是否输出原图比例的截图
      original: false, // 上传图片按照原始比例渲染
      centerBox: false, // 截图框是否被限制在图片里面
      infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
    }
  }),
  created(){
    const userId = this.$store.state.user.userId
    const token = this.$store.state.user.token

    this.$utils.doGetAxios(this, '/api/user/set', {
      params:{userId},
      headers: {token }
    },(data)=>{
      this.user = data
      this.option.img = this.user.avatar
    })
  },
  methods:{
    updateAccount(){
      // 保证数据合法
      if(!this.$refs.form.validate()){
        return
      }

      this.$messageBox.confirm('确认修改账户信息？', '修改', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const token = this.$store.state.user.token

        this.$utils.doPutAxios(this, '/api/user', this.$qs.stringify(this.user), {
          headers: {token }
        },(data, msg)=>{
          this.$message.success(msg)

          const user = {
            userId: this.user.userId,
            name: this.user.name,
            avatar: this.user.avatar,
            token
          }
          // 更新修改后的用户
          this.$store.commit('LOGIN_USER', user)
          localStorage.setItem('userId', user.userId)
          localStorage.setItem('token', user.token)
        })
      }).catch(()=>{})

    },
    realTime(data) {
      this.previews = data
    },
    handleChangeUpload(e) {
      const file = e.target.files[0]
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG/PNG 格式!');
          return false
      }
      if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
          return false
      }
      // 上传成功后将图片地址赋值给裁剪框显示图片
      this.$nextTick(async () => {
          this.option.img = URL.createObjectURL(file)
      })
    },
    updateImage(){
      const token = this.$store.state.user.token
      const userId = this.$store.state.user.userId

      this.$refs.cropper.getCropBlob(data => {
        let formData = new FormData()
        formData.append('file', data)
        formData.append('userId', userId)
        this.$axios({
          method: 'post',
          url: '/api/upload/avatar',
          data: formData,
          headers: {
            token,
            'Content-Type': 'multipart/form-data'
          }
        }).then(rep => {
          const res = rep.data
          if(res.status == 200){
            this.$message.success(res.msg)
            this.user.avatar = res.data
            this.dialog = false
          }else{
            this.$message.error(res.msg)
          }
        }).catch(()=> {})

      })
    }
  }
}
</script>

<style>
#cut{
  display: flex;
  align-items: center;
}
#show-cropper{
  width: 300px;
  height: 300px;
}
#show-preview > div{
  overflow: hidden;
  border: 1px solid rgb(204, 198, 198);
  border-radius:50%; 
}
/* 花条垂直线 */
#vertical-line{
  width: 1px;
  height: 320px;
  background: rgb(204, 198, 198);
  margin: 0 auto;
}
#show-preview > p{
  font-size: x-small;
  color: rgb(204, 198, 198);
  text-align: center;
  margin-top: 10px;
}
</style>